package graphicinterface;

import java.awt.Color;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.LinkedList;

import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;

import bookworm.BookCoverAndHowManyDaysToFinishIt;



public class WindowHowLongToFinishBook implements MouseListener, ActionListener
{
	private JTextField textFieldToTypeBookName;
	/**
	 * panelsearchForHowLongToFinishBook is a panel which initially
	 * will have a textField for the user to specify the book name,
	 * then it will change to a list of books found with the name specified.
	 * Finally, it will contain the book cover, it's title and days taken to read book 
	 */
	private JPanel panelSearchForHowLongToFinishBook;
	private JFrame mainWindowHowLongToFinishBook;
	
	/**
	 * label with image containing the character which will appear on the left side of screen. It will be the helper.
	 */
	private JLabel labelWithImageHelperCharacter;
	
	/**
	 * has the user already typed the book name?This boolean will be helpful to warn our system
	 * when it must start the search for a book in reading history.
	 */
	private boolean userAlreadyTypedBookName;
	
	/**
	 * after the user specifies a book name, the system will show him/her books in book histories
	 * related to this name.
	 */
	private LinkedList<JLabel> booksRelatedToSpecifiedBookName;
	
	private JGradientButton buttonStartNewSearch;
	private JGradientButton buttonConfirm;
	
	
	public WindowHowLongToFinishBook()
	{
		this.mainWindowHowLongToFinishBook = new JFrameWithMenu("how long to finish book");
		
		//let's just initialize some variables...
		this.userAlreadyTypedBookName = false;//window is just about to be open, so...
		this.booksRelatedToSpecifiedBookName = new LinkedList<JLabel>();//initially, the user hasn't specified any book name yet.
		
		this.drawScreenHowLongToFinishBook();
	}
	
	private JPanel createPanelWindowTitle()
	{
		JPanel windowTitle = new JPanel();
		windowTitle.setBackground(new Color(255, 131, 137));
		windowTitle.setBorder(BorderFactory.createLineBorder(Color.BLACK, 3));
		JLabel labelTitle = TextLabelCreator.createStyledTextlabel("How long does it take to read book?", 30);
		windowTitle.add(labelTitle);
		return windowTitle;
	}
	
	private JPanel createPanelHelperCharacter()
	{
		JPanel panelHelperCharacter = new JPanel();
		panelHelperCharacter.setBackground(new Color(255, 131, 137));
		ImageIcon imageHelper = CreatesImageIcon.createImageIcon("images/nekomascot2.png", "neko mascot");
		this.labelWithImageHelperCharacter = new JLabel(imageHelper);
		panelHelperCharacter.add(labelWithImageHelperCharacter);
		return panelHelperCharacter;
	}
	
	private JPanel createPanelSpecifyBookName()
	{
		JPanel panelSpecifyBook = new JPanel();
		panelSpecifyBook.setBackground(new Color(255, 131, 137));
		panelSpecifyBook.setBorder(BorderFactory.createLineBorder(Color.BLACK, 3));
		panelSpecifyBook.setPreferredSize(new Dimension(450, 400));
		
		this.textFieldToTypeBookName = new JTextField(20);
		JLabel labelTypeBookName = TextLabelCreator.createStyledTextlabel("what's the book name?", 30);
		
		GridBagLayout layoutPanelSpecifiBook = new GridBagLayout();
		panelSpecifyBook.setLayout(layoutPanelSpecifiBook);
		GridBagConstraints g = new GridBagConstraints();
		g.gridx = 0;
		g.gridy = 0;
		panelSpecifyBook.add(labelTypeBookName, g);
		g.gridy = 1;
		panelSpecifyBook.add(textFieldToTypeBookName, g);
		
		return panelSpecifyBook;
	}
	
	/**
	 * creates panel and buttons to make a new search or go back to main menu
	 * @return
	 */
	private JPanel createPanelButtons()
	{
		JPanel panelButtons = new JPanel();
		panelButtons.setBackground(new Color(255, 131, 137));
		this.buttonConfirm = new JGradientButton("Confirm");
		this.buttonConfirm.addActionListener(this);
		this.buttonStartNewSearch = new JGradientButton("start new search");
		this.buttonStartNewSearch.addActionListener(this);
		panelButtons.add(buttonConfirm);
		panelButtons.add(buttonStartNewSearch);
		return panelButtons;
		
	}
	
	

	
	private void drawScreenHowLongToFinishBook()
	{
		//first, let's create the contents of the window!
		JPanel panelWithWindowTitle = this.createPanelWindowTitle();
		this.panelSearchForHowLongToFinishBook = new JPanel();
		this.panelSearchForHowLongToFinishBook.setBackground(Color.BLACK);
		JPanel panelSpecifyBookName = this.createPanelSpecifyBookName();
		this.panelSearchForHowLongToFinishBook.add(panelSpecifyBookName);
		JPanel panelWithHelperCharacter = this.createPanelHelperCharacter();
		JPanel panelWithButtons = this.createPanelButtons();
		
		//let's put all these window contents together!
		JPanelWithBackgroundImage panelHowLongToFinishBook = new JPanelWithBackgroundImage("backgroundbookworm.jpg");
		GridBagLayout layoutMainPanel = new GridBagLayout();
		panelHowLongToFinishBook.setLayout(layoutMainPanel);
		GridBagConstraints g = new GridBagConstraints();
		g.gridx = 0;
		g.gridy = 0;
		g.gridheight = 1;
		g.gridwidth = 10;
		g.insets = new Insets(0, 0, 10, 0);
		panelHowLongToFinishBook.add(panelWithWindowTitle, g);
		g.gridy = 1;
		g.gridheight = 5;
		g.gridwidth = 4;
		g.insets = new Insets(0, 0, 0, 20);
		panelHowLongToFinishBook.add(panelWithHelperCharacter, g);
		g.gridx = 4;
		g.gridy = 3;
		g.gridwidth = 1;
		g.gridheight = 1;
		g.insets = new Insets(0, 0, 0, 0);
		panelHowLongToFinishBook.add(panelSearchForHowLongToFinishBook, g);
		g.gridy = 5;
		g.gridheight = 1;
		g.anchor = GridBagConstraints.SOUTH;
		panelHowLongToFinishBook.add(panelWithButtons, g);
		
		this.mainWindowHowLongToFinishBook.add(panelHowLongToFinishBook);
		this.mainWindowHowLongToFinishBook.setVisible(true);
	}
	
	
	
	/**
	 * after the user types a book name, or system will search for books with this name
	 * in various book histories. Then, it will show the user the results.
	 */
	public void showBookNameResults(LinkedList<String> bookNames)
	{
		LinkedList<JLabel> labelsRelatedBooknames = new LinkedList<JLabel>();
		for(int i =0; i < bookNames.size(); i++)
		{
			String singleBookName = bookNames.get(i);
			JLabel singleBookNameLabel = TextLabelCreator.createStyledTextlabel(singleBookName);
			/*	these labels can be chosen by the user. 
				If he/she selects it, it will give him/her an average time to read the book.
			*/
			singleBookNameLabel.addMouseListener(this);
			
			labelsRelatedBooknames.add(singleBookNameLabel);
		}
		
		this.booksRelatedToSpecifiedBookName = labelsRelatedBooknames;
		
		JPanel panelWithBookResults = new JPanel();
		panelWithBookResults.setBackground(new Color(255, 131, 137));
		panelWithBookResults.setBorder(BorderFactory.createLineBorder(Color.BLACK, 3));
		
		int totalBookResults = bookNames.size();
		GridLayout layoutPanelWithBookResults = new GridLayout(totalBookResults, 1);
		panelWithBookResults.setLayout(layoutPanelWithBookResults);
		for(int i = 0; i < this.booksRelatedToSpecifiedBookName.size(); i++)
		{
			JLabel singleBookResultLabel = this.booksRelatedToSpecifiedBookName.get(i);
			panelWithBookResults.add(singleBookResultLabel);
		}
		
		//let's add a scrollPane for the panel in case the book titles get too long
		JScrollPane scrollPaneForBookResult = new JScrollPane();
		Dimension d = new Dimension(400, 400);
		scrollPaneForBookResult.setPreferredSize(d);
		scrollPaneForBookResult.setViewportView(panelWithBookResults);
		
		//let's now display this panel with book names to the user!
		this.panelSearchForHowLongToFinishBook.removeAll();
		this.panelSearchForHowLongToFinishBook.add(scrollPaneForBookResult);
		this.panelSearchForHowLongToFinishBook.updateUI();	
		
		//let's update the helper character too!
		ImageIcon helperMascotImage = CreatesImageIcon.createImageIcon("images/nekomascotyoumean.png", "neko girl mascot");
		this.updateHelperMascot(helperMascotImage);
		
	}
	
	public void updateHelperMascot(ImageIcon newImage)
	{
		this.labelWithImageHelperCharacter.setIcon(newImage);
	}
	
	@Override
	public void actionPerformed(ActionEvent e) 
	{
		//first, let's change cursor because it can take a while to process data
		this.mainWindowHowLongToFinishBook.setCursor(new Cursor(Cursor.WAIT_CURSOR));
		Object source = e.getSource();
		if(source == this.buttonConfirm)
		{
			
			this.buttonConfirm.setEnabled(false);
			
			if(this.userAlreadyTypedBookName == false)
			{
				this.userAlreadyTypedBookName = true;
				SystemFunctionalitiesFacade functionalitiesFacade =
						SystemFunctionalitiesFacade.getInstance();
				String bookNameUserTyped = this.textFieldToTypeBookName.getText();
				LinkedList<String> booksWithNameSpecified = 
						functionalitiesFacade.findBooksInHistoryWithThisTitle(bookNameUserTyped);
				if(booksWithNameSpecified.size() > 0)
				{
					this.showBookNameResults(booksWithNameSpecified);
				}
				else
				{
					//no books found. Let's just update the mascot for a new search
					ImageIcon newMascotImage = CreatesImageIcon.createImageIcon("images/nekomascotnotfound.png", "book not found mascot");
					this.updateHelperMascot(newMascotImage);
					//then the user can type a new search.
					this.userAlreadyTypedBookName = false;
					this.textFieldToTypeBookName.setText("");
					this.buttonConfirm.setEnabled(true);
				}
			}
		}
		else if(source == this.buttonStartNewSearch)
		{
			this.startNewSearch();
		}
		
		//let's change the cursor back to where it was before loading
		this.mainWindowHowLongToFinishBook.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
		
	}
	
	/**
	 * after user clicked on button "start new search", the system prepares the screen for a new search.
	 */
	public void startNewSearch()
	{
		//if the confirm button is disabled, we must enable it to the next search!
		this.buttonConfirm.setEnabled(true);
		this.userAlreadyTypedBookName = false;//new search
		//we must also change the helper character;
		ImageIcon helperCharacterImage = CreatesImageIcon.createImageIcon("images/nekomascot2.png", "nekoGirl specify a book");
		this.updateHelperMascot(helperCharacterImage);
		
		JPanel panelSpecifyBookName = this.createPanelSpecifyBookName();
		this.panelSearchForHowLongToFinishBook.removeAll();
		this.panelSearchForHowLongToFinishBook.add(panelSpecifyBookName);
		this.panelSearchForHowLongToFinishBook.updateUI();
		
	}

	
	
	/**
	 * has the user clicked on a book title label?
	 * The user clicks on a book title label to discover the average reading time of a book.
	 * @param arg0 mouse event of the click
	 * @return if the user clicked on a book title label
	 */
	private boolean userClickedInABookTitleLabel(MouseEvent arg0)
	{
		Object objectClicked = arg0.getSource();
		for(int i = 0; i < this.booksRelatedToSpecifiedBookName.size(); i++)
		{
			JLabel labelBookTitle = this.booksRelatedToSpecifiedBookName.get(i);
			if(objectClicked == labelBookTitle)
			{
				return true;
			}
		}
		return false;
	}
	
	private JLabel getBookTitleUserJustClicked(MouseEvent arg0)
	{
		Object objectClicked = arg0.getSource();
		for(int i = 0; i < this.booksRelatedToSpecifiedBookName.size(); i++)
		{
			JLabel labelBookTitle = this.booksRelatedToSpecifiedBookName.get(i);
			if(objectClicked == labelBookTitle)
			{
				return labelBookTitle;
			}
		}
		return null;
	}

	

	@Override
	public void mouseClicked(MouseEvent arg0) 
	{
		
		if(this.userClickedInABookTitleLabel(arg0) == true)
		{
			//the user clicked in a book title label, then we must show the book's average reading time for the user
			JLabel bookTitleSelectedByUser = this.getBookTitleUserJustClicked(arg0);
			String stringBookTitleSelected = bookTitleSelectedByUser.getText();
			this.showResultsHowLongToReadBook(stringBookTitleSelected);
			
		}
	}
	
	public void showResultsHowLongToReadBook(String bookTitle)
	{
		/*
		 * who calculates the average time to read a book isn't the interface! It must ask
		 * the facade to get it's job done.
		 */
		SystemFunctionalitiesFacade functionalitiesFacade = SystemFunctionalitiesFacade.getInstance();
		BookCoverAndHowManyDaysToFinishIt bookCoverAndDaysToFinishIt =
				functionalitiesFacade.howManyDaysToFinishThisBook(bookTitle);
		//now let's prepare the results to the user!
		JPanel panelResults = new JPanel();
		panelResults.setBackground(new Color(255,131,137));
		String bookCoverAddress = bookCoverAndDaysToFinishIt.getBookCoverAddress();
		ImageIcon bookCover = GetsBookCoverByImageAddress.getBookCover(bookCoverAddress);
		JLabel labelBookCover = new JLabel(bookCover);
		long daysToFinishBook =bookCoverAndDaysToFinishIt.getHowManyDaysToFinishBook();
		JLabel labelDaysToFinishBook = TextLabelCreator.createStyledTextlabel("it takes " + daysToFinishBook + " day(s) to finish this book");
		
		
		GridLayout layoutpanel = new GridLayout(2, 1);
		panelResults.setLayout(layoutpanel);
		panelResults.add(labelBookCover);
		panelResults.add(labelDaysToFinishBook);
		
		this.panelSearchForHowLongToFinishBook.removeAll();
		this.panelSearchForHowLongToFinishBook.add(panelResults);
		this.panelSearchForHowLongToFinishBook.updateUI();
		
		//finally, we'll update our helper character
		ImageIcon newHelperCharacterImage = CreatesImageIcon.createImageIcon("images/nekomascotreadbook.png", "nekogirl read book");
		this.labelWithImageHelperCharacter.setIcon(newHelperCharacterImage);
		
	}

	@Override
	public void mouseEntered(MouseEvent arg0) 
	{
		Component objectEntered = arg0.getComponent();
		objectEntered.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
	}

	@Override
	public void mouseExited(MouseEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mousePressed(MouseEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mouseReleased(MouseEvent arg0) {
		// TODO Auto-generated method stub
		
	}


}
